﻿using Bird.Core.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Bird.Services.Events
{
    public class EventSubscriptionService : IEventSubcriptionService
    {

        private Dictionary<Type, List<object>> _watchers = new Dictionary<Type, List<object>>();

        private ReaderWriterLock _lock = new ReaderWriterLock();
        private WriterLock BeginWrite()
        {
            return new WriterLock(_lock);
        }
        private ReaderLock BeginRead()
        {
            return new ReaderLock(_lock);
        }
       
        public void AddEventWatcher<T>(IEventWatcher<T> watcher)
        {
            if (watcher == null)
                throw new ArgumentNullException("watcher");
            using (BeginWrite())
            {
                List<object> watchers;
                Type watcherType = typeof(T);
                if (!_watchers.TryGetValue(watcherType, out watchers))
                {
                    watchers = new List<object>();
                    _watchers.Add(watcherType, watchers);
                }
                if (!watchers.Contains(watcher))
                    watchers.Add(watcher);
            }
        }

        public void RemoveEventWatcher<T>(IEventWatcher<T> watcher)
        {
            if (watcher == null)
                throw new ArgumentNullException("watcher");
            using (BeginWrite())
            {
                List<object> watchers;
                if (_watchers.TryGetValue(typeof(T), out watchers))
                {
                    if (watchers.Contains(watcher))
                        watchers.Remove(watcher);
                }
            }
        }

        public IList<IEventWatcher<T>> GetEventWatchers<T>()
        {
            using (BeginRead())
            {
                List<object> watchers;
                List<IEventWatcher<T>> value = new List<IEventWatcher<T>>();
                if (_watchers.TryGetValue(typeof(T), out watchers))
                {
                    foreach (var item in watchers)
                        value.Add((IEventWatcher<T>)item);
                }
                return value;
            }
        }


     
    }
}
